package utils

import (
	"errors"
	"reflect"
)

type DbOperationFn func(olditem interface{}, newitem interface{}) error
type CompareFn func(olditem interface{}, newitem interface{}) bool
func UpdateDbList(oldlist interface{}, newlist interface{}, compare SliceCompareWith2ItemFn, AddFn DbOperationFn, DelFn DbOperationFn, UpdateFn DbOperationFn) error {
    //用反射技术遍历oldlist和newlist

	oldlistVal := reflect.ValueOf(oldlist)
	oldlistkind := oldlistVal.Kind()

	newlistVal := reflect.ValueOf(newlist)
	newlistkind := newlistVal.Kind()
	if oldlistkind != reflect.Slice && oldlistkind != reflect.Array {
		return errors.New("SliceAny only supoort slice and array type")
	}

	if newlistkind != reflect.Slice && newlistkind != reflect.Array {
		return errors.New("SliceAny only supoort slice and array type")
	}

	//删除操作逻辑
	for i := 0; i < oldlistVal.Len(); i++ {
		item := oldlistVal.Index(i).Interface()
		resultItem, err := SliceFindFirstWhere2(newlist, item, compare)
		if err != nil {
			return err
		}

		if resultItem == nil {
			err := DelFn(item, nil)
			if err != nil {
				return err
			}
		}
	}


	//更新操作逻辑和新增操纵逻辑
	for i := 0; i < newlistVal.Len(); i++ {
		item := newlistVal.Index(i).Interface()
		resultItem, err := SliceFindFirstWhere2(oldlist, item, compare)
		if err != nil {
			return err
		}

		//
		if resultItem == nil {
			err := AddFn(nil, item)
			if err != nil {
				return err
			}
		} else {
			err := UpdateFn(resultItem, item)
			if err != nil {
				return err
			}
		}
	}

    return nil
}